package cn.itsource.ymcc.service.impl;

import cn.itsource.ymcc.client.UaaFeignClient;
import cn.itsource.ymcc.constants.BaseConstants;
import cn.itsource.ymcc.domain.Login;
import cn.itsource.ymcc.domain.User;
import cn.itsource.ymcc.domain.UserAccount;
import cn.itsource.ymcc.domain.UserBaseInfo;
import cn.itsource.ymcc.dto.RegisterParamDto;
import cn.itsource.ymcc.mapper.UserBaseInfoMapper;
import cn.itsource.ymcc.mapper.UserMapper;
import cn.itsource.ymcc.result.JSONResult;
import cn.itsource.ymcc.service.IUserAccountService;
import cn.itsource.ymcc.service.IUserService;
import cn.itsource.ymcc.to.VerifyCode2Cache;
import cn.itsource.ymcc.util.AssertUtil;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import io.seata.spring.annotation.GlobalTransactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.Date;

/**
 * <p>
 * 会员登录账号 服务实现类
 * </p>
 *
 * @author whale
 * @since 2021-09-23
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    @Autowired
    private RedisTemplate<Object,Object> redisTemplate;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private UserBaseInfoMapper userBaseInfoMapper;

    @Autowired
    private UaaFeignClient uaaFeignClient;

    @Autowired
    private IUserAccountService userAccountService;

    @GlobalTransactional(rollbackFor = Exception.class)
    @Override
    public void register(RegisterParamDto dto) {
        //1.基本参数校验
        String mobile = dto.getMobile();
        String password = dto.getPassword();
        Integer regChannel = dto.getRegChannel();
        String smsCode = dto.getSmsCode();
        AssertUtil.isPhone(mobile,"无效的手机号");
        AssertUtil.isNotEmpty(password,"密码不能为空");
        AssertUtil.isNotNull(regChannel,"无效的参数regChannel");
        AssertUtil.isNotEmpty(smsCode,"手机验证码不能为空");

        //2.手机号是否已经被注册
        User userFormDB = baseMapper.selectByPhone(mobile);
        AssertUtil.isNull(userFormDB,"手机号已经被注册");
        //3.短信验证码是否正确
        //3.1.从Redis中获取验证码发送记录
        //key: 前缀+手机号
        String smsKey = String.format("SMS:%s",mobile );
        VerifyCode2Cache smsCode2Cache = (VerifyCode2Cache) redisTemplate.opsForValue().get(smsKey);
        AssertUtil.isNotNull(smsCode2Cache,"无效的验证码");
        //3.2.redis中的验证码和传入的参数的验证码比较
        AssertUtil.isEqualsIgnoreCase( smsCode2Cache.getCode(),smsCode,"手机验证码错误，请重新发送");


        //保存Login=====================================================
        Login login = new Login();
        login.setPassword(passwordEncoder.encode(password));
        //头像
        login.setAvatar("https://img2.baidu.com/it/u=1535346744,3172439964&fm=26&fmt=auto");
        //前台用户分配的客户端ID
        login.setClientId("website");
        login.setClientSecret("123");
        login.setType(BaseConstants.Login.TYPE_USER);
        login.setUsername(mobile);
        JSONResult jsonResult = uaaFeignClient.save(login);
        AssertUtil.isTrue(jsonResult.isSuccess(),"登录信息保存失败");
        AssertUtil.isNotNull(jsonResult.getData(),"登录信息保存失败");

        Long loginId = Long.valueOf(jsonResult.getData().toString());


        //4.保存用户信息VipUser
        long time = new Date().getTime();
        User user = new User();
        user.setCreateTime(time);
        user.setPhone(mobile);

        //密码加密
        user.setNickName(mobile);
        //增加手机的位状态
        user.addBitState(BaseConstants.User.STATE_PHONE);
        user.setLoginId(loginId);
        baseMapper.insert(user);

        //4.1.密码加密
        //5.保存VipBase关联表
        UserBaseInfo vipBase = new UserBaseInfo();
        vipBase.setCreateTime(time);
        vipBase.setRegChannel(regChannel);
        vipBase.setRegTime(time);
        vipBase.setUserId(user.getId());
        userBaseInfoMapper.insert(vipBase);

        UserAccount userAccount = new UserAccount();
        userAccount.setId(user.getId());
        userAccountService.insert(userAccount);
        //int i = 1 / 0;
    }
}
